package com.example.ffepeg.ffmTestIng;

import java.io.BufferedReader;
import java.io.InputStreamReader;

//时长有点偏差
public class FFMpegHandler {
    public static void main(String[] args) {
        String videoFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\file\\3652234199995.mp4";
        String audioFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\file\\bde84f969d55.wav";
        String outputFile = "D:\\javaXM\\FFEpeg\\src\\main\\resources\\out\\output.mp4";

        try {
            // 获取视频和音频的时长
            float videoDuration = getMediaDuration(videoFile);
            float audioDuration = getMediaDuration(audioFile);

            if (videoDuration > audioDuration) {
                // 视频大于音频，截取视频到音频长度
                executeCommand(new String[]{"ffmpeg", "-i", videoFile, "-i", audioFile, "-map", "0:v", "-map", "1:a", "-shortest", outputFile});
            } else {
                // 音频大于视频，循环视频直到音频结束
                int repeatCount = (int) Math.ceil(audioDuration / videoDuration);
                StringBuilder fileListContent = new StringBuilder();
                for (int i = 0; i < repeatCount; i++) {
                    fileListContent.append("file '").append(videoFile).append("'\n");
                }
                String fileListPath = "src/main/resources/file/filespaths/input.txt";
                // 将视频文件列表写入文件
                java.nio.file.Files.write(java.nio.file.Paths.get(fileListPath), fileListContent.toString().getBytes());

                // 执行合并命令
                executeCommand(new String[]{"ffmpeg", "-f", "concat", "-safe", "0", "-i", fileListPath, "-i", audioFile, "-map", "0:v", "-map", "1:a", "-vsync", "vfr", outputFile});
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static float getMediaDuration(String mediaFile) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", mediaFile);
        Process process = pb.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        return Float.parseFloat(line);
    }

    private static void executeCommand(String[] command) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.inheritIO(); // 直接继承父进程的标准输入、输出和错误流
        Process process = pb.start();
        if (process.waitFor() != 0) {
            throw new RuntimeException("Failed to execute command: " + String.join(" ", command));
        }
    }
}
